package com.ratingbay.console.naivequery;

 
import java.util.Iterator;
import java.util.List;
import java.util.ArrayList;
 
import javax.persistence.EntityManager;
import javax.persistence.EntityManagerFactory;
import javax.persistence.Query;
import javax.persistence.EntityTransaction;

import com.ratingbay.console.model.*;
import com.ratingbay.lucene.LuceneIndex;

public class IndexNaiveQuery{
	private IndexNaiveQuery(){
	}
	private static IndexNaiveQuery instance = null;
    public static IndexNaiveQuery getInstance(){
    	if(null == instance){
    		instance = new IndexNaiveQuery();
    	}
        return instance;
    }

    //for cjob
    public Long getTwitterUsersCount(){

        EntityManagerFactory emf = NaiveQuery.getInstance().getEntityManagerFactory();
        EntityManager em = emf.createEntityManager();

        String sql = "SELECT count(*) FROM twitter_user";
        Query query =  em.createNativeQuery(sql);

        Long count = (Long) query.getSingleResult();
        em.close();
        return count;
    }
    
  //for cjob
    public Long getLuceneIndexId(){

        EntityManagerFactory emf = NaiveQuery.getInstance().getEntityManagerFactory();
        EntityManager em = emf.createEntityManager();

        String sql = "SELECT * FROM lucene_user_index";
        Query query =  em.createNativeQuery(sql);

        List<Long> ls=query.getResultList();
        em.close();
        if(ls!=null&&!ls.isEmpty())
        	return ls.get(0);
        else
        	return null;
    }
    
    public List<Object[]> getTwitterUsersBiggerThanId(long id){

        EntityManagerFactory emf = NaiveQuery.getInstance().getEntityManagerFactory();
        EntityManager em = emf.createEntityManager();

        String sql = "SELECT user_id,username,user_followers_count,user_friends_count,user_tweets_count" +
        		" FROM twitter_user where id>"+id+" ORDER BY id  ";
        Query query =  em.createNativeQuery(sql);

        List<Object[]> objectArrayList = query.getResultList();
        em.close();
        return objectArrayList;
    }
    
    public Long getTwitterUsersMaxIdBiggerThanId(long id){

        EntityManagerFactory emf = NaiveQuery.getInstance().getEntityManagerFactory();
        EntityManager em = emf.createEntityManager();

        String sql = "SELECT MAX(id) FROM twitter_user where id>"+id;
        Query query =  em.createNativeQuery(sql);

        List<Long> ls=query.getResultList();
        em.close();
        if(ls!=null&&!ls.isEmpty())
        	return ls.get(0);
        else
        	return null;
    }
    
    //for cjob
    public List<Object[]> getTwitterUsers(int pageNum, int pageSize){

        EntityManagerFactory emf = NaiveQuery.getInstance().getEntityManagerFactory();
        EntityManager em = emf.createEntityManager();

        Long limit = (long)pageSize;
        Long offset = (long)pageNum * pageSize;
        String sql = "SELECT user_id,username,user_followers_count,user_friends_count,user_tweets_count" +
        		" FROM twitter_user ORDER BY id  LIMIT " + limit + " OFFSET " + offset;
        Query query =  em.createNativeQuery(sql);

        List<Object[]> objectArrayList = query.getResultList();
        em.close();
        return objectArrayList;
    }

    //cjob entry
    public int indexTwitterUserCountPageNum = 0;
    public int indexTwitterUserPageSize = 10000;
    public void indexTwitterUser() {
        
        int pageNum = this.indexTwitterUserCountPageNum;
        int pageSize = this.indexTwitterUserPageSize;
        long count=getTwitterUsersCount();
        System.out.println("CJOB start indexTwitterUser pageNo is "+pageNum);
		
		if( this.indexTwitterUserCountPageNum>count/this.indexTwitterUserPageSize){
			System.out.println("CJOB end IndexTwitterUser final");
			return;
		}
		
        List<Object[]> twitterUsers = this.getTwitterUsers(pageNum, pageSize);
        Iterator<Object[]> it = twitterUsers.iterator();
        
        Object[] twitterUser;
        List<TwitterUser> ll=new ArrayList<TwitterUser>();
		while(it.hasNext()){
			twitterUser = it.next();
			TwitterUser u = new TwitterUser();
			u.setUserId( (Long)twitterUser[0] );
			u.setUsername( (String)twitterUser[1] );
			u.setUserFollowersCount( (Long)twitterUser[2] );
			u.setUserFriendsCount( (Long)twitterUser[3] );
			u.setUserTweetsCount( (Long)twitterUser[4] );
			ll.add(u);
		}
		if(!ll.isEmpty())
			LuceneIndex.getInstance().index(ll);
			
        if(twitterUsers.size() < 1){
            //this.indexTwitterUserCountPageNum = 0;
            System.out.println("CJOB indexTweetCount all once");
        }else{
            this.indexTwitterUserCountPageNum ++;
        }

        System.out.println("CJOB end IndexTwitterUser");
    }
    
    public void indexAppendTwitterUser() {
        
    	Long id=getLuceneIndexId();
		
        List<Object[]> twitterUsers = this.getTwitterUsersBiggerThanId(id);
        Long maxId = this.getTwitterUsersMaxIdBiggerThanId(id);
        
        if(twitterUsers==null||twitterUsers.isEmpty()){
        	System.out.println("CJOB index append no new datas");
        	return;
        }
        Iterator<Object[]> it = twitterUsers.iterator();
        
        Object[] twitterUser;
        List<TwitterUser> ll=new ArrayList<TwitterUser>();
		while(it.hasNext()){
			twitterUser = it.next();
			TwitterUser u = new TwitterUser();
			u.setUserId( (Long)twitterUser[0] );
			u.setUsername( (String)twitterUser[1] );
			u.setUserFollowersCount( (Long)twitterUser[2] );
			u.setUserFriendsCount( (Long)twitterUser[3] );
			u.setUserTweetsCount( (Long)twitterUser[4] );
			ll.add(u);
		}
		if(!ll.isEmpty()){
			LuceneIndex.getInstance().index(ll);
			System.out.println("append new index "+ll.size());
		}
		
		updateLuceneUserIndexId(maxId);

        System.out.println("CJOB end IndexTwitterUser");
    }

    public void updateLuceneUserIndexId(Long id) {

        EntityManagerFactory emf = NaiveQuery.getInstance().getEntityManagerFactory();
        EntityManager em = emf.createEntityManager();
        String sql = "UPDATE lucene_user_index SET id = " + id;
        EntityTransaction tx = em.getTransaction();
        tx.begin();
        Query query = em.createNativeQuery(sql);
        query.executeUpdate();
        tx.commit();
        System.out.println("CJOB end updateLuceneUserIndexId");
    }
    
    
}